<?php
/**
 * Smithy PHP library
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * Smithy is a free Zend Framework based PHP library.
 *
 * @category   Smithy
 * @package    Smithy_Model
 * @subpackage Gateway
 * @copyright  Copyright (c) 2008-2009 Kovács Tamás
 * @license    New BSD License
 * @version    $Id: Abstract.php ktamas $
 */

/**
 * A basic model gateway class.
 *
 * Defines some common model related functions.
 *
 * @author Kovács Tamás
 * @category Smithy
 * @package Smithy_Model
 * @subpackage Gateway
 */
abstract class Smithy_Model_Gateway_Abstract
{
    /**
     * @var array Zend_Db_Table_Abstract instances
     */
    protected static $_tables = array();

    /**
     * @var array Zend_Form instances
     */
    protected static $_forms = array();

    /**
     * @var array Smithy_Model_Gateway_Abstract instances
     */
    protected static $_models = array();

    /**
     * Default module name
     *
     * @var string|null
     */
    protected $_moduleName = null;

    /**
     * Primary table for the model.
     *
     * @var string
     */
    protected $_primaryTable = null;


    /**
     * Constructor
     *
     * @return void
     */
    public function __construct()
    {
        $this->init();
    }

    /**
     * Initialize gateway.
     *
     * @return void
     */
    public function init()
    {}

    /**
     * Returns with the models main select.
     *
     * @return Zend_Db_Table_Select
     */
    protected function _select()
    {
    	return $this->getTable($this->_primaryTable)->select();
    }

    /**
     * Get table class
     *
     * @param string $name
     * @param string|null $moduleName [OPTIONAL]
     * @return Smithy_Db_Table_Abstract
     */
    public function getTable($name, $moduleName=null)
    {
        $name  = ucfirst($name);
        $moduleName = null === $moduleName ? $this->_moduleName : ucfirst($moduleName);

        if (!array_key_exists($moduleName . 'DbTable_' . $name, self::$_tables)) {
            $class = Smithy_Loader::loadResource($name, 'DbTable', $moduleName);
            self::$_tables[$moduleName . 'DbTable_' . $name] = new $class;
        }
        return self::$_tables[$moduleName . 'DbTable_' . $name];
    }

    /**
     * Get form instace
     *
     * @param  string $name
     * @param string|null $moduleName [OPTIONAL]
     * @return Zend_Form
     */
    public function getForm($name, $moduleName=null)
    {
        $name  = ucfirst($name);
        $moduleName = null === $moduleName ? $this->_moduleName : ucfirst($moduleName);

        if (!array_key_exists($moduleName . 'Form_' . $name, self::$_forms)) {
            $class = Smithy_Loader::loadResource($name, 'Form', $moduleName);
            self::$_forms[$moduleName . 'Form_' . $name] = new $class;
        }
        return self::$_forms[$moduleName . 'Form_' . $name];
    }

    /**
     * Get model instace
     *
     * @param  string $name
     * @param string|null $moduleName [OPTIONAL]
     * @return Smithy_Model_Gateway_Abstract
     */
    public function getModel($name, $moduleName=null)
    {
        $name  = ucfirst($name);
        $moduleName = null === $moduleName ? $this->_moduleName : ucfirst($moduleName);

        if (!array_key_exists($moduleName . $name, self::$_models)) {
            $class = Smithy_Loader::loadResource($name, '', $moduleName);
            self::$_models[$moduleName . $name] = new $class;
        }
        return self::$_models[$moduleName . $name];
    }

    /**
     * Insert or update a row
     *
     * @param  array $info New or updated row data
     * @param  string|null Table name to use
     * @return int Row ID of saved row
     */
    public function save(array $info, $tableName = null)
    {
        $table = $this->getTable($tableName);
        $id    = null;
        $row   = null;
        if (array_key_exists('id', $info)) {
            $id = $info['id'];
            unset($info['id']);
            $matches = $table->find($id);
            if (0 < count($matches)) {
                $row = $matches->current();
            }
        }
        if (null === $row) {
            $row = $table->createRow();
        }

        $columns = $table->info('cols');
        foreach ($columns as $column) {
            if (array_key_exists($column, $info)) {
                $row->$column = $info[$column];
            }
        }

        return $row->save();
    }
}
